home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / c / savedec31.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-07  |  7.1 KB  |  250 lines

  1. /*
  2.  Copyright (C) 1994 M. Hagiya, W. Schelter, T. Yuasa
  3.  
  4. This file is part of GNU Common Lisp, herein referred to as GCL
  5.  
  6. GCL is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. GCL is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public 
  14. License for more details.
  15.  
  16. You should have received a copy of the GNU Library General Public License 
  17. along with GCL; see the file COPYING.  If not, write to the Free Software
  18. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. */
  21.  
  22. /*
  23.         unixsave.c
  24. */
  25.  
  26.  
  27. #ifdef HAVE_FCNTL
  28. #include <fcntl.h>
  29. #else
  30. #include <sys/file.h>
  31. #endif
  32.  
  33. #ifdef HAVE_AOUT
  34. #undef BSD
  35. #undef ATT
  36. #define BSD
  37. #endif
  38.  
  39.  
  40.  
  41. #ifdef BSD
  42. #include <a.out.h>
  43. #endif
  44.  
  45.  
  46. #ifdef ATT
  47. #include <syms.h>
  48. #include <filehdr.h>
  49. #include <aouthdr.h>
  50. #include <scnhdr.h>
  51. #endif
  52.  
  53. #ifdef E15
  54. #include <a.out.h>
  55. extern  etext;
  56. #endif
  57.  
  58.  
  59. filecpy(to, from, n)
  60. FILE *to, *from;
  61. register int n;
  62. {
  63.         char buffer[BUFSIZ];
  64.  
  65.         for (;;)
  66.                 if (n > BUFSIZ) {
  67.                         fread(buffer, BUFSIZ, 1, from);
  68.                         fwrite(buffer, BUFSIZ, 1, to);
  69.                         n -= BUFSIZ;
  70.                 } else if (n > 0) {
  71.                         fread(buffer, 1, n, from);
  72.                         fwrite(buffer, 1, n, to);
  73.                         break;
  74.                 } else
  75.                         break;
  76. }
  77.  
  78.  
  79. memory_save(original_file, save_file)
  80. char *original_file, *save_file;
  81. {       /* MEM_SAVE_LOCALS; */
  82.  
  83.         struct filehdr Ehdr;
  84.         struct aouthdr header;
  85.         struct scnhdr shdr[10];
  86.         HDRR symhdr;
  87.  
  88.           struct scnhdr *text_section;
  89.           struct scnhdr *rdata_section;
  90.           struct scnhdr *data_section;
  91.           struct scnhdr *lit8_section;
  92.           struct scnhdr *lit4_section;
  93.           struct scnhdr *sdata_section;
  94.           struct scnhdr *sbss_section;
  95.           struct scnhdr *bss_section;
  96.  
  97.         char *data_begin, *data_end;
  98.         int original_data;
  99.         FILE *original, *save;
  100.         register int n;
  101.         register char *p;
  102.         extern char *sbrk();
  103.         extern char stdin_buf[BUFSIZ], stdout_buf[BUFSIZ];
  104.  
  105.         fclose(stdin);
  106.         original = fopen(original_file, "r");
  107.         if (stdin != original || original->_file != 0) {
  108.                 fprintf(stderr, "Can't open the original file.\n");
  109.                 exit(1);
  110.         }
  111.         setbuf(original, stdin_buf);
  112.         fclose(stdout);
  113.         unlink(save_file);
  114.         n = open(save_file, O_CREAT|O_WRONLY, 0777);
  115.         if (n != 1 || (save = fdopen(n, "w")) != stdout) {
  116.                 fprintf(stderr, "Can't open the save file.\n");
  117.                 exit(1);
  118.         }
  119.         setbuf(save, stdout_buf);
  120.  
  121.         fread(&Ehdr,sizeof(Ehdr),1,original);
  122.         fread(&header,Ehdr.f_opthdr, 1,original);
  123.         {int i=0;
  124.          int pagesize = getpagesize();
  125. /*       core_end = (char *)((int) (core_end + pagesize - 1) & ~(pagesize - 1));
  126. */
  127.  
  128. #define READ_SCNHDR(name,str)  \
  129.          name = &shdr[i]; \
  130.            fread(name,sizeof(struct scnhdr),1,original); \
  131.              if(strcmp(str,(name)->s_name)) printf("got %s not %s sections", \
  132.                            (name)->s_name,str); i++;
  133.          READ_SCNHDR(text_section,".text") ;
  134.          READ_SCNHDR(rdata_section,".rdata");
  135.          READ_SCNHDR(data_section,".data");
  136.          READ_SCNHDR(lit8_section, ".lit8");
  137.          READ_SCNHDR(lit4_section, ".lit4");
  138.          READ_SCNHDR(sdata_section, ".sdata");
  139.          READ_SCNHDR(sbss_section,".sbss");
  140.          READ_SCNHDR(bss_section,".bss");
  141.          if(i!= Ehdr.f_nscns) printf("wrong number of sections");
  142.        }
  143. /*
  144.         READ_HEADER;
  145.         FILECPY_HEADER;
  146.         */
  147. #define ALTER_SCN(name,size,addr,scnptr) (name)->s_size = size; \
  148.          (name)->s_paddr = addr; \
  149.          (name)->s_vaddr = addr; \
  150.          (name)->s_scnptr = scnptr;
  151.  
  152.          original_data = header.a_data;
  153.  
  154.          data_begin =  (char *)rdata_section->s_vaddr;
  155.          header.a_data =        (int) core_end - rdata_section->s_vaddr;
  156.          header.a_bss = 0;
  157.  
  158.  
  159.          ALTER_SCN(data_section, header.a_data - rdata_section->s_size
  160.                    ,data_section->s_vaddr, data_section->s_scnptr);
  161.          ALTER_SCN(lit4_section,0,data_section->s_vaddr,data_section->s_scnptr);
  162.          ALTER_SCN(lit8_section,0,data_section->s_vaddr,data_section->s_scnptr);
  163.          ALTER_SCN(sbss_section,0,data_section->s_vaddr,data_section->s_scnptr);
  164.          ALTER_SCN(sdata_section,0,data_section->s_vaddr,data_section->s_scnptr)
  165. ;
  166.          ALTER_SCN(bss_section,0, /* sbrk(0) - core_end,*/
  167.                    data_section->s_vaddr,data_section->s_scnptr);
  168.  
  169.          header.bsize = bss_section->s_size;
  170.          Ehdr.f_symptr += (header.dsize - original_data);
  171.  
  172.          fwrite(&Ehdr,1,sizeof(Ehdr),save);
  173.          fwrite(&header,1,Ehdr.f_opthdr,save);
  174.          fwrite(&shdr[0],sizeof(struct scnhdr),Ehdr.f_nscns,save);
  175.          filecpy(save,original,rdata_section->s_scnptr - ftell(save));
  176. /*       p = data_begin; n= header.a_data;
  177.          while(--n>=0)
  178.            {putc(*p,save);          p++;} */
  179.  
  180.          for (n = header.a_data, p = data_begin;  ;  n -= BUFSIZ, p += BUFSIZ)
  181.            {    {int jj;
  182.                  jj = ftell(save);}
  183.  
  184.  
  185.  
  186.                 if (n > BUFSIZ)
  187.                         fwrite(p, BUFSIZ, 1, save);
  188.                 else if (n > 0) {
  189.                         fwrite(p, 1, n, save);
  190.                         break;
  191.                 } else
  192.                         break;}
  193.  
  194.         fseek(original, original_data, 1);
  195.  
  196.  
  197.         COPY_TO_SAVE;
  198.         {int diff = (header.dsize - original_data);
  199.          fseek(original,Ehdr.f_symptr - diff,0);
  200.          fread(&symhdr,sizeof(symhdr),1,original);
  201.          if(symhdr.cbLineOffset)symhdr.cbLineOffset+= diff;
  202.          if(symhdr.cbDnOffset)symhdr.cbDnOffset+= diff;
  203.          if(symhdr.cbPdOffset)symhdr.cbPdOffset+= diff;
  204.          if(symhdr.cbSymOffset)symhdr.cbSymOffset+= diff;
  205.          if(symhdr.cbOptOffset)symhdr.cbOptOffset+= diff;
  206.          if(symhdr.cbAuxOffset)symhdr.cbAuxOffset+= diff;
  207.          if(symhdr.cbSsOffset)symhdr.cbSsOffset+= diff;
  208.          if(symhdr.cbSsExtOffset)symhdr.cbSsExtOffset+= diff;
  209.          if(symhdr.cbFdOffset)symhdr.cbFdOffset+= diff;
  210.          if(symhdr.cbRfdOffset)symhdr.cbRfdOffset+= diff;
  211.          if(symhdr.cbExtOffset)symhdr.cbExtOffset+= diff;
  212.          fseek(save,Ehdr.f_symptr ,0);
  213.          fwrite(&symhdr,sizeof(symhdr),1,save);
  214.        }
  215.  
  216.         fclose(original);
  217.         fclose(save);
  218. }
  219.  
  220. Lsave()
  221. {
  222.         char filename[256];
  223.  
  224.         check_arg(1);
  225.         check_type_or_pathname_string_symbol_stream(&vs_base[0]);
  226.         coerce_to_filename(vs_base[0], filename);
  227.  
  228.         _cleanup();
  229. /*
  230.         {
  231.                 FILE *p;
  232.                 int nfile;
  233.  
  234.  
  235.                 nfile = NUMBER_OPEN_FILES;
  236.  
  237.                 for (p = &_iob[3];  p < &_iob[nfile];  p++)
  238.                         fclose(p);
  239.         }
  240. */
  241.         memory_save(kcl_self, filename);
  242. /*
  243.         _exit(0);
  244. */
  245.         exit(0);
  246.  
  247.         /*  no return  */
  248. }
  249.  
  250.